package jnote;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.*;

public class FontChooser extends JDialog implements ActionListener {
    private final List fontList = new List(8);
    private final List fontDimList = new List(8);
    private JCheckBox bold = new JCheckBox();
    private JCheckBox italic = new JCheckBox();
    private Font font;
    private int fontDim;
    private boolean isBold;
    private boolean isItalic;
    private final String fontPreview = "Font Preview";
    private String fontName = "";
    private final String fontArray[];
    private final int DEFAULT_SIZE = 7;
    
    /*
     * Vector containing the possible font dimensions
     */
    private final String fontDimArray[] = { 
        "8", "10", "11", "12", "14",
        "16", "18", "20", "24", "30",
        "36", "40", "48", "60", "72"
    };
    
    private final JLabel preview = new JLabel(fontPreview, JLabel.CENTER);
    private final JButton jbApply = new JButton("Apply");
    private final JButton jbCancel = new JButton("Cancel");
    private final JButton jbPreview = new JButton("Preview");
    
    private final Panel top = new Panel();
    private final Panel options = new Panel();
    private final Panel panel = new Panel();
    
    /*
     * Variable used to store the old font data
     */
    private Font oldFont;
    
    FontChooser(Font f) {
        setTitle("Font Chooser");
        setModal(true);
        
        /* 
         * Save a copy of the old font just in case 
         * the operation is canceled, in order to restore the old one
         */
        oldFont = f;
        
        top.setLayout(new FlowLayout());

        /*
         * Add the fonts to the panel
         */
        top.add(fontList);
        
        /*
         * Get the available fonts
         */
        fontArray = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

        /*
         * Add the fonts into a List
         */
        for(String s : fontArray) {
            fontList.add(s);
        }

        /*
         * Find the current font
         * and highlight it into the list
         */
        fontList.select(findFont(oldFont, fontList));
        
        /*
         * Add the dimensions to the panel
         */
        top.add(fontDimList);
        
        /*
         * Add the dimensions into a List
         */
        for(String s : fontDimArray) {
            fontDimList.add(s);
        }
        
        /* 
         * Select a default font size
         */
        fontDimList.select(DEFAULT_SIZE);

        getContentPane().add(top, BorderLayout.NORTH);
        
        top.add(options);
        options.setLayout(new GridLayout(0, 1));
        options.add(bold = new JCheckBox("Bold", false));
        options.add(italic = new JCheckBox("Italic", false));

        preview.setSize(200, 50);
        getContentPane().add(preview, BorderLayout.CENTER);

        panel.add(jbApply);
        jbApply.addActionListener(this);

        panel.add(jbPreview);
        jbPreview.addActionListener(this);
        
        panel.add(jbCancel);
        jbCancel.addActionListener(this);

        getContentPane().add(panel, BorderLayout.SOUTH);
        previewFont();

        /*
         * Pack the window and center it
         */
        pack();
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        
        addWindowListener(new WindowListener() {
            @Override
            public void windowOpened(WindowEvent e) {
            }

            @Override
            public void windowClosing(WindowEvent e) {
                /*
                 * If the operation is canceled, the old font is restored
                 */
                font = oldFont;
                fontName = oldFont.getName();
                fontDim = oldFont.getSize();
                isBold = oldFont.isBold();
                isItalic = oldFont.isItalic();
                dispose();
            }

            @Override
            public void windowClosed(WindowEvent e) {
            }

            @Override
            public void windowIconified(WindowEvent e) {
            }

            @Override
            public void windowDeiconified(WindowEvent e) {
            }

            @Override
            public void windowActivated(WindowEvent e) {
            }

            @Override
            public void windowDeactivated(WindowEvent e) {
            }
        });
    }

    private int findFont(Font f, List l) {
        boolean found = false;
        int i = 0;
        
        do {
            if(!(f.getName().equalsIgnoreCase(l.getItem(i)))) {
                i++;
            } else {
                found = true;
            }
        }
        while(!found);
        
        return i;
    }

    private void previewFont() {
        String fontNameDim = fontDimList.getSelectedItem();
        int dimension = Integer.parseInt(fontNameDim);
        int type = Font.PLAIN;
        
        fontName = fontList.getSelectedItem();
        isBold = bold.isSelected();
        isItalic = italic.isSelected();
        
        if(isBold) {
            type = Font.BOLD;
        }
        if(isItalic) {
            type = Font.ITALIC;
        }
        
        font = new Font(fontName, type, dimension);
        preview.setFont(font);
        
        pack();
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == jbCancel) {
            font = oldFont;
            fontName = oldFont.getName();
            fontDim = oldFont.getSize();
            isBold = oldFont.isBold();
            isItalic = oldFont.isItalic();
            dispose();
        } else if(e.getSource() == jbApply) {
            previewFont();
            dispose();
        } else if(e.getSource() == jbPreview) {
            previewFont();
        }
    }

    public Font getSelectedFont() {
        return font;
    }
}
